package roteador;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Timer;
import java.util.TimerTask;

public class Enlace {

    private static final long TEMPO_ATIVO = 1000;
    private static final long TIME_OUT = 5000;
    private int destinoID, porta, peso;
    private Roteador origem;
    private InetAddress ip;
    private Timer ativo, timeOut;

    public Enlace(Roteador origem, int destinoID, InetAddress ip, int porta, int peso) {
        this.origem = origem;
        this.destinoID = destinoID;
        this.ip = ip;
        this.peso = peso;
        this.porta = porta;
        ativo = new Timer("Anunciador de Atividade do roteador " + destinoID);
        ativo.schedule(new Anunciador(), TEMPO_ATIVO, TEMPO_ATIVO);
        timeOut = new Timer("Anunciador de timeout " + destinoID);
        timeOut.schedule(new TimeOut(), TIME_OUT, TIME_OUT);
    }

    public int getDestinoID() {
        return this.destinoID;
    }

    public int getOrigemID() {
        return this.origem.getID();
    }

    public InetAddress getIP() {
        return this.ip;
    }

    public int getPorta() {
        return this.porta;
    }

    public int getPeso() {
        return this.peso;
    }

    public void setPeso(int novoCusto) {
        this.peso = novoCusto;
    }

    public synchronized void cancelar() {
        System.out.println("Finalizando Enlace do roteador: " + getOrigemID() + " para o roteador: " + getDestinoID());
        timeOut.cancel();
        ativo.cancel();
        origem.cancelarEnlace(this);

    }

    public synchronized void envia(byte[] message) {
        try {
            DatagramSocket socket = new DatagramSocket();
            DatagramPacket pacote = new DatagramPacket(message, message.length, getIP(), getPorta());
            socket.send(pacote);
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void reiniciar() {
        timeOut.cancel();
        timeOut = new Timer("Anunciador de timeout " + destinoID);
        timeOut.schedule(new TimeOut(), TIME_OUT, TIME_OUT);
    }

    class Anunciador extends TimerTask {

        @Override
        public void run() {
            byte[] mensagem = new byte[Listener.TAMANHO_PACOTE];
            byte[] alive = origem.getVetorDistancia();
            for (int i = 0; i < alive.length; i++) {
                mensagem[i] = alive[i];
            }
            Enlace.this.envia(mensagem);

        }
    }

    class TimeOut extends TimerTask {

        @Override
        public void run() {
            System.out.println("enlace morto");
            Enlace.this.cancelar();
        }
    }
}
